<html>
 <head>
  <meta charset="utf-8"/>
  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"/>
  <title>
   智擒啤酒小贼：使用 Python 和 OpenCV 检测和跟踪运动对象  | 数螺 | NAUT IDEA
  </title>
  <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet"/>
  <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
  <style type="text/css">
   #xmain img {
                  max-width: 100%;
                  display: block;
                  margin-top: 10px;
                  margin-bottom: 10px;
                }

                #xmain p {
                    line-height:150%;
                    font-size: 16px;
                    margin-top: 20px;
                }

                #xmain h2 {
                    font-size: 24px;
                }

                #xmain h3 {
                    font-size: 20px;
                }

                #xmain h4 {
                    font-size: 18px;
                }


                .header {
	           background-color: #0099ff;
	           color: #ffffff;
	           margin-bottom: 20px;
	        }

	        .header p {
                  margin: 0px;
                  padding: 10px 0;
                  display: inline-block;  
                  vertical-align: middle;
                  font-size: 16px;
               }

               .header a {
                 color: white;
               }

              .header img {
                 height: 25px;
              }
  </style>
  <script src="http://cdn.bootcss.com/jquery/3.0.0/jquery.min.js">
  </script>
  <script src="http://nautstatic-10007657.file.myqcloud.com/static/css/readability.min.js" type="text/javascript">
  </script>
  <script type="text/javascript">
   $(document).ready(function() {
                 var loc = document.location;
                 var uri = {
                  spec: "http://dataunion.org/19514.html",
                  host: "http://dataunion.org",
                  prePath: "http://dataunion.org",
                  scheme: "http",
                  pathBase: "http://dataunion.org/"
                 };
    
                 var documentClone = document.cloneNode(true);
                 var article = new Readability(uri, documentClone).parse();
     
                 document.getElementById("xmain").innerHTML = article.content;
                });
  </script>
  <!-- 1466461336: Accept with keywords: (title(0.166666666667):社区,Python,数盟,对象,啤酒,贼, topn(0.366666666667):初始化,背景,数盟,像素,数据挖掘,轮廓,遍历,文章,结果,Python,假设,计算,图像,方法,阀值,图片,视频,python,前景,视频流,元组,视频文件,树莓,数据,代码,系统,区域,差值,啤酒,摄像头).-->
 </head>
 <body onload="">
  <div class="header">
   <div class="container">
    <div class="row">
     <div class="col-xs-6 col-sm-6 text-left">
      <a href="/databee">
       <img src="http://nautidea-10007657.cos.myqcloud.com/logo_white.png"/>
      </a>
      <a href="/databee">
       <p>
        数螺
       </p>
      </a>
     </div>
     <div class="hidden-xs col-sm-6 text-right">
      <p>
       致力于数据科学的推广和知识传播
      </p>
     </div>
    </div>
   </div>
  </div>
  <div class="container text-center">
   <h1>
    智擒啤酒小贼：使用 Python 和 OpenCV 检测和跟踪运动对象
   </h1>
  </div>
  <div class="container" id="xmain">
   ﻿﻿
   <title>
    智擒啤酒小贼：使用 Python 和 OpenCV 检测和跟踪运动对象 | 数盟社区
   </title>
   <!-- All in One SEO Pack 2.2.7.6.2 by Michael Torbert of Semper Fi Web Design[32,82] -->
   <!-- /all in one seo pack -->
   <!--
<div align="center">
<a href="http://strata.oreilly.com.cn/hadoop-big-data-cn?cmp=mp-data-confreg-home-stcn16_dataunion_pc" target="_blank"><img src="http://dataunion.org/wp-content/uploads/2016/05/stratabj.jpg"/ ></a>
</div>
-->
   <header id="header-web">
    <div class="header-main">
     <hgroup class="logo">
      <h1>
       <a href="http://dataunion.org/" rel="home" title="数盟社区">
        <img src="http://dataunion.org/wp-content/themes/yzipi/images/logo.png"/>
       </a>
      </h1>
     </hgroup>
     <!--logo-->
     <nav class="header-nav">
      <ul class="menu" id="menu-%e4%b8%bb%e8%8f%9c%e5%8d%95">
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-71" id="menu-item-71">
        <a href="http://dataunion.org/category/events" title="events">
         活动
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-22457" id="menu-item-22457">
          <a href="http://dataunion.org/2016timeline">
           2016档期
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-22459" id="menu-item-22459">
          <a href="http://dataunion.org/category/parterc">
           合作会议
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor current-menu-parent current-post-parent menu-item-has-children menu-item-20869" id="menu-item-20869">
        <a href="http://dataunion.org/category/tech" title="articles">
         文章
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20867" id="menu-item-20867">
          <a href="http://dataunion.org/category/tech/base" title="base">
           基础架构
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3302" id="menu-item-3302">
          <a href="http://dataunion.org/category/tech/ai" title="ai">
           人工智能
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3303" id="menu-item-3303">
          <a href="http://dataunion.org/category/tech/analysis" title="analysis">
           数据分析
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21920" id="menu-item-21920">
          <a href="http://dataunion.org/category/tech/dm">
           数据挖掘
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3314" id="menu-item-3314">
          <a href="http://dataunion.org/category/tech/viz" title="viz">
           可视化
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3305" id="menu-item-3305">
          <a href="http://dataunion.org/category/tech/devl" title="devl">
           编程语言
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-20876" id="menu-item-20876">
        <a href="http://dataunion.org/category/industry">
         行业
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-16328" id="menu-item-16328">
          <a href="http://dataunion.org/category/industry/case" title="case">
           行业应用
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2112" id="menu-item-2112">
          <a href="http://dataunion.org/category/industry/demo" title="demo">
           Demo展示
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21562" id="menu-item-21562">
          <a href="http://dataunion.org/category/industry/news">
           行业资讯
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-311" id="menu-item-311">
        <a href="http://dataunion.org/category/sources" title="sources">
         资源
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20870" id="menu-item-20870">
        <a href="http://dataunion.org/category/books" title="book">
         图书
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21363" id="menu-item-21363">
        <a href="http://dataunion.org/category/training">
         课程
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-21853" id="menu-item-21853">
        <a href="http://dataunion.org/category/jobs">
         职位
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-22050" id="menu-item-22050">
          <a href="http://dataunion.org/category/career">
           职业规划
          </a>
         </li>
        </ul>
       </li>
      </ul>
     </nav>
     <!--header-nav-->
    </div>
   </header>
   <!--header-web-->
   <div id="main">
    <div id="soutab">
     <form action="http://dataunion.org/" class="search" method="get">
     </form>
    </div>
    <div id="container">
     <nav id="mbx">
      当前位置：
      <a href="http://dataunion.org">
       首页
      </a>
      &gt;
      <a href="http://dataunion.org/category/tech">
       文章
      </a>
      &gt;  正文
     </nav>
     <!--mbx-->
     <article class="content">
      <header align="centre" class="contenttitle">
       <div class="mscc">
        <h1 class="mscctitle">
         <a href="http://dataunion.org/19514.html">
          智擒啤酒小贼：使用 Python 和 OpenCV 检测和跟踪运动对象
         </a>
        </h1>
        <address class="msccaddress ">
         <em>
          1,494 次阅读 -
         </em>
         <a href="http://dataunion.org/category/tech" rel="category tag">
          文章
         </a>
        </address>
       </div>
      </header>
      <div class="content-text">
       <p>
        出处：
        <a href="http://python.jobbole.com/81593/">
         伯乐在线
        </a>
       </p>
       <header>
        <div class="header-wrapper">
        </div>
        <div class="clear">
        </div>
       </header>
       <div class="clear">
        <img src="http://dataunion.org/wp-content/uploads/2015/06/6941baebgw1et0jklm4j9g20h20cg1kx.gif"/>
       </div>
       <div class="grid-8">
        <div class="post-81593 post type-post status-publish format-standard hentry category-python tag-opencv tag-python odd" id="post-81593">
         <div class="entry">
          <p>
           这个该死的家伙。我就知道他偷了我最后一罐啤酒！
          </p>
          <p>
           对于一个男人来讲，这些话永远都不该说。但是当我关上冰箱门的时候，我愤怒地叹息，感到厌恶，自言自语地说了这些。
          </p>
          <p>
           你看，我花了12个小时写了这篇将要发表的文章《
           <a href="http://www.pyimagesearch.com/pyimagesearch-gurus/">
            PyImageSearch Gurus course
           </a>
           》。我的脑子都糊掉了，像个半熟的摊鸡蛋一样，几乎要从耳朵里流出来了。当我深夜决定结束工作的时候，我只想放松一下，看看我最爱的电影——《侏罗纪公园》。同时喝着来自 Smuttynose 的最好的 IPA 冰啤，Smuttynose 是近来我非常喜欢的一家酒厂。
          </p>
          <p>
           但是，昨天晚上来串门的该死的 James 喝掉了我最后一罐啤酒。
          </p>
          <p>
           好吧，据称。
          </p>
          <p>
           <strong>
            我并不能证明任何我的猜测
           </strong>
           。实际上，我并没有亲眼看到他喝我的啤酒，因为我埋头于笔记本电脑中，手指在键盘上跳动，兴奋地敲击出教程和文章。但是我感觉他就是嫌疑犯。他是我唯一会喝 IPA 的（前）朋友。
          </p>
          <p>
           所以我做了一件任何男人都会做的事。
          </p>
          <p>
           <strong>
            我在橱柜顶上安装了一个树莓派，来探测看他是不是打算再次偷啤酒。
           </strong>
          </p>
          <p>
           <a class="qa-blog-zoom" href="http://dataunion.org/wp-content/uploads/2015/06/6941baebgw1et0jkkhkc3j20rs111tct_副本.jpg">
            <img src="http://dataunion.org/wp-content/uploads/2015/06/6941baebgw1et0jkkhkc3j20rs111tct_副本.jpg"/>
           </a>
          </p>
          <p>
           过分了？
          </p>
          <p>
           也许吧。
          </p>
          <p>
           但是，我很看重我的啤酒。而且如果 James 再次尝试偷我的啤酒的话，我会逮他个正着。
          </p>
          <p>
           一篇关于运动检测的系列文章（分为两部分）
          </p>
          <p>
           <strong>
            做一个用于家庭监控的运动检测和追踪系统，
           </strong>
           分两部分，本文是第一篇。
          </p>
          <p>
           本文接下来的部分，将会详细介绍如何使用计算机视觉技术来建立一个用于家庭监控的基础的运动检测和追踪系统。本例对预先录制的视频和网络摄像头的实时数据流都可以工作；然而，我们将会在我们的笔记本/桌面电脑上进行开发。
          </p>
          <p>
           在本系列的第二部分中，我会向你展示如何升级代码，使其可以在树莓派和camera board上工作，以及如何扩展家庭监控系统，来捕捉任何检测到的运动，并且上传到你的个人Dropbox中。
          </p>
          <p>
           也许到了最后，我们可以把 James 抓个正着。
          </p>
          <h2>
           一点关于背景移除的内容
          </h2>
          <p>
           背景移除是很多计算机视觉应用的关键内容。我们通过它来计算经过收费站的汽车个数。我们通过它来计算进进出出一间商店的人的个数。
          </p>
          <p>
           <em>
            同时我们使用它来进行运动检测。
           </em>
          </p>
          <p>
           在本文开始写代码之前，让我告诉你，OpenCV 里有很多很多方法来进行运动检测、追踪和分析。有一些非常简单，而另外一些非常复杂。两个初级的方法是某种形式的基于混合高斯模型的前景和背景分割：
          </p>
          <ol>
           <li>
            KaewTraKulPong 等人发表的《
            <em>
             <a href="http://www.ee.surrey.ac.uk/CVSSP/Publications/papers/KaewTraKulPong-AVBS01.pdf" target="_blank">
              An improved adaptive background mixture model for real-time tracking with shadow detection
             </a>
             &gt;
            </em>
            。这个方法可以通过
            <code>
             cv2.BackgroundSubtractorMOG
            </code>
            来使用。
           </li>
           <li>
            Zivkovic 提出的《
            <a href="http://www.zoranz.net/Publications/zivkovic2004ICPR.pdf" target="_blank">
             Improved adaptive Gaussian mixture model for background subtraction
            </a>
            》和《
            <a href="http://www.zoranz.net/Publications/zivkovicPRL2006.pdf" target="_blank">
             Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction
            </a>
            》。可以通过
            <code>
             cv2.BackgroundSubtractorMOG2
            </code>
            来使用。
           </li>
          </ol>
          <p>
           在新版本的 OpenCV 中，我们有基于贝叶斯（概率）的前景和背景分割，是 Godbehere 等人在2012年的文章中实现的，《
           <a href="http://goldberg.berkeley.edu/pubs/acc-2012-visual-tracking-final.pdf">
            Visual Tracking of Human Visitors under Variable-Lighting Conditions for a Responsive Audio Art Installation
           </a>
           》，我们可以在
           <code>
            cv2.createBackgroundSubtractorGMG
           </code>
           中找到它的实现（然而我们需要等OpenCV 3的到来，才能使用它的全部功能。）
          </p>
          <p>
           所有这些方法都涉及到从前景中分离背景（它们甚至提供相应的机制来让我们辨别实际运动和阴影及关照的细微改变）！
          </p>
          <p>
           为什么这一点特别重要？为什么我们这么在意哪个像素属于前景哪个像素属于背景？
          </p>
          <p>
           在运动检测中，我们会做出如下的假设：
          </p>
          <p>
           <strong>
            我们视频流中的背景在连续的视频帧内，多数时候应该是静止不变的，因此如果我们可以建立背景模型，我们的就可以监视到显著的变化。如果发生了显著的变化，我们就可以检测到它——通常这些变化和我们视频中的运动有关。
           </strong>
          </p>
          <p>
           显然在现实世界中，我们这个假设比较容易失效。因为阴影、反色、光照条件以及环境中可能发生的其他变化，我们的背景可能会看上去变得非常不同，这会让我们的算法失效。所以为什么最成功的背景移除/前景检测系统需要固定安装的相机以及控制光照条件。
          </p>
          <p>
           上面我提到的方法，尽管非常强大，但同时计算非常耗时。而且我们最终的目标是在本系列的最后，把该系统部署在树莓派上，因此我们最好可以坚持使用简单的方法。我们将在未来的文章中回到这些强大的方法上，但是目前我们将保持简单和高效。
          </p>
          <h2>
           用 Python 和 OpenCV 进行基础的运动检测和追踪
          </h2>
          <p>
           好了，准备好帮助我开发一个家用监视系统来抓住那个偷啤酒的混蛋了么？ 打开编辑器，新建一个文件，命名为
           <strong>
            motion_detector.py
           </strong>
           ，然后让我们开始写代码吧。
          </p>
         </div>
         <blockquote>
          <div class="line number1 index0 alt2">
           <code class="python comments">
            # 导入必要的软件包
           </code>
          </div>
          <div class="line number2 index1 alt1">
           <code class="python keyword">
            import
           </code>
           <code class="python plain">
            argparse
           </code>
          </div>
          <div class="line number3 index2 alt2">
           <code class="python keyword">
            import
           </code>
           <code class="python plain">
            datetime
           </code>
          </div>
          <div class="line number4 index3 alt1">
           <code class="python keyword">
            import
           </code>
           <code class="python plain">
            imutils
           </code>
          </div>
          <div class="line number5 index4 alt2">
           <code class="python keyword">
            import
           </code>
           <code class="python plain">
            time
           </code>
          </div>
          <div class="line number6 index5 alt1">
           <code class="python keyword">
            import
           </code>
           <code class="python plain">
            cv2
           </code>
          </div>
          <div class="line number8 index7 alt1">
           <code class="python comments">
            # 创建参数解析器并解析参数
           </code>
          </div>
          <div class="line number9 index8 alt2">
           <code class="python plain">
            ap
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            argparse.ArgumentParser()
           </code>
          </div>
          <div class="line number10 index9 alt1">
           <code class="python plain">
            ap.add_argument(
           </code>
           <code class="python string">
            "-v"
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python string">
            "--video"
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python functions">
            help
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python string">
            "path to the video file"
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number11 index10 alt2">
           <code class="python plain">
            ap.add_argument(
           </code>
           <code class="python string">
            "-a"
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python string">
            "--min-area"
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python functions">
            type
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python functions">
            int
           </code>
           <code class="python plain">
            , default
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python value">
            500
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python functions">
            help
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python string">
            "minimum area size"
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number12 index11 alt1">
           <code class="python plain">
            args
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python functions">
            vars
           </code>
           <code class="python plain">
            (ap.parse_args())
           </code>
          </div>
          <div class="line number14 index13 alt1">
           <code class="python comments">
            # 如果video参数为None，那么我们从摄像头读取数据
           </code>
          </div>
          <div class="line number15 index14 alt2">
           <code class="python keyword">
            if
           </code>
           <code class="python plain">
            args.get(
           </code>
           <code class="python string">
            "video"
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python color1">
            None
           </code>
           <code class="python plain">
            )
           </code>
           <code class="python keyword">
            is
           </code>
           <code class="python color1">
            None
           </code>
           <code class="python plain">
            :
           </code>
          </div>
          <div class="line number16 index15 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            camera
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            cv2.VideoCapture(
           </code>
           <code class="python value">
            0
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number17 index16 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            time.sleep(
           </code>
           <code class="python value">
            0.25
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number19 index18 alt2">
           <code class="python comments">
            # 否则我们读取一个视频文件
           </code>
          </div>
          <div class="line number20 index19 alt1">
           <code class="python keyword">
            else
           </code>
           <code class="python plain">
            :
           </code>
          </div>
          <div class="line number21 index20 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            camera
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            cv2.VideoCapture(args[
           </code>
           <code class="python string">
            "video"
           </code>
           <code class="python plain">
            ])
           </code>
          </div>
          <div class="line number23 index22 alt2">
           <code class="python comments">
            # 初始化视频流的第一帧
           </code>
          </div>
          <div class="line number24 index23 alt1">
           <code class="python plain">
            firstFrame
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python color1">
            None
           </code>
          </div>
         </blockquote>
         <div class="entry">
          <div>
          </div>
          <p>
           <strong>
            2-6行
           </strong>
           导入了我们必要的软件包。这些看上去都很熟悉，除了
           <code>
            imutils
           </code>
           这个包，它提供了一组由我编写的非常方便的函数，来让我们更简单的进行图像处理。如果你还没有安装
           <a href="https://github.com/jrosebr1/imutils">
            imutils
           </a>
           到你的系统，你可以通过pip来安装：
           <code>
            pip install imutils
           </code>
          </p>
          <p>
           下一步，我们在
           <strong>
            9-12行
           </strong>
           解析了命令行参数。我们定义了两个选项。第一个，
           <code>
            --video
           </code>
           ，是可选的。它会指定一个路径，指向一个预先录制好的视频文件，我们可以检测该视频中的运动。如果你不提供视频的路径，那么OpenCV会从你的摄像头中来检测运动。
          </p>
          <p>
           我们同时还定义了
           <code>
            --min-area
           </code>
           ，它表示一个图像区域被看做实际运动的最小尺寸（以像素为单位）。正如我接下来要讲的那样，我们会发现图像中比较小的区域变化会比较显著，可能是因为噪点或是光线的变化。在实际中，这些小区域并不是实际的运动——所以我们定义一个最小的尺寸来对付和过滤掉这些假阳性（false-positives）结果。
          </p>
          <p>
           <strong>
            15-21行
           </strong>
           获取一个我们摄像机对象的引用。在这个例子中，没有提供视频路径（
           <strong>
            15-17行
           </strong>
           ），我们会取得一个摄像头的引用。如果提供了一个视频文件路径，那么我们会在
           <strong>
            20-21行
           </strong>
           建立一个指向它的指针。
          </p>
          <p>
           最后，我们以一个变量来结束这段代码，这个变量是
           <code>
            firstFrame
           </code>
           。 能猜到
           <code>
            firstFrame
           </code>
           是什么吗？
          </p>
          <p>
           <strong>
            假设
           </strong>
           ：
           <em>
            视频的第一帧不会包含运动，而仅仅是背景——因此我们可以使用第一帧来建立背景模型。
           </em>
           显然我们此处建立的假设有些太大了。但是再说一次，我们的目标是要在树莓派上运行这个系统，所以我们不能做的太复杂。正如你会在本文的结果一节所看到的那样，当有人在屋里走动的时候，我们可以轻易的检测到运动并追踪他们。
          </p>
         </div>
         <blockquote>
          <div class="line number1 index0 alt2">
           <code class="python comments">
            # 遍历视频的每一帧
           </code>
          </div>
          <div class="line number2 index1 alt1">
           <code class="python keyword">
            while
           </code>
           <code class="python color1">
            True
           </code>
           <code class="python plain">
            :
           </code>
          </div>
          <div class="line number3 index2 alt2">
           <code class="python spaces">
           </code>
           <code class="python comments">
            # 获取当前帧并初始化occupied/unoccupied文本
           </code>
          </div>
          <div class="line number4 index3 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            (grabbed, frame)
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            camera.read()
           </code>
          </div>
          <div class="line number5 index4 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            text
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python string">
            "Unoccupied"
           </code>
          </div>
          <div class="line number7 index6 alt2">
           <code class="python spaces">
           </code>
           <code class="python comments">
            # 如果不能抓取到一帧，说明我们到了视频的结尾
           </code>
          </div>
          <div class="line number8 index7 alt1">
           <code class="python spaces">
           </code>
           <code class="python keyword">
            if
           </code>
           <code class="python keyword">
            not
           </code>
           <code class="python plain">
            grabbed:
           </code>
          </div>
          <div class="line number9 index8 alt2">
           <code class="python spaces">
           </code>
           <code class="python keyword">
            break
           </code>
          </div>
          <div class="line number11 index10 alt2">
           <code class="python spaces">
           </code>
           <code class="python comments">
            # 调整该帧的大小，转换为灰阶图像并且对其进行高斯模糊
           </code>
          </div>
          <div class="line number12 index11 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            frame
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            imutils.resize(frame, width
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python value">
            500
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number13 index12 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            gray
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
           </code>
          </div>
          <div class="line number14 index13 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            gray
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            cv2.GaussianBlur(gray, (
           </code>
           <code class="python value">
            21
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python value">
            21
           </code>
           <code class="python plain">
            ),
           </code>
           <code class="python value">
            0
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number16 index15 alt1">
           <code class="python spaces">
           </code>
           <code class="python comments">
            # 如果第一帧是None，对其进行初始化
           </code>
          </div>
          <div class="line number17 index16 alt2">
           <code class="python spaces">
           </code>
           <code class="python keyword">
            if
           </code>
           <code class="python plain">
            firstFrame
           </code>
           <code class="python keyword">
            is
           </code>
           <code class="python color1">
            None
           </code>
           <code class="python plain">
            :
           </code>
          </div>
          <div class="line number18 index17 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            firstFrame
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            gray
           </code>
          </div>
          <div class="line number19 index18 alt2">
           <code class="python spaces">
           </code>
           <code class="python keyword">
            continue
           </code>
          </div>
         </blockquote>
         <div class="entry">
          <div>
          </div>
          <p>
           现在我们已经获取了视频文件/摄像头数据流的引用，我们可以在第一行（原文第27行）开始遍历每一帧了。
          </p>
          <p>
           调用
           <code>
            camera.read()
           </code>
           为我们返回一个2元组。元组的第一个值是
           <code>
            grabbed
           </code>
           ，表明是否成功从缓冲中读取了
           <code>
            frame
           </code>
           。元组的第二个值就是
           <code>
            frame
           </code>
           它本身。
          </p>
          <p>
           我们同时还定义了一个叫做
           <code>
            text
           </code>
           的字符串，并对其进行初始化来表明我们正在监控的这个房间“没有被占领”（Unoccupied）。如果这个房间确实有活动，我们可以更新这个字符串。
          </p>
          <p>
           在这个例子中，如果没有成功从视频文件中读取一帧，我们会在10-11行（原文35-36行）跳出循环。
          </p>
          <p>
           我们可以开始处理帧数据并准备进行运动分析（
           <strong>
            15-17行
           </strong>
           ）。我们首先会调整它的大小到500像素宽——没有必要去直接处理视频流中的大尺寸，原始图像。我们同样会把图片转换为灰阶图像，因为彩色数据对我们的运动检测算法没有影响。最后，我们会使用高斯模糊来平滑我们的图像。
          </p>
          <p>
           认识到即使是相邻帧，也不是完全相同的这一点很重要！
          </p>
          <p>
           由于数码相机传感器的微小变化，没有100%相同的两帧数据——一些像素肯定会有不同的强度值。也就是说，我们需要，并应用高斯平滑对一个
           <em>
            11X11
           </em>
           的区域的像素强度进行平均。这能帮我们滤除可能使我们运动检测算法失效的高频噪音。
          </p>
          <p>
           正如我在上面提到的，我们需要通过某种方式对我们的图像进行背景建模。再一次的，我们会假设视频的第一帧不包含任何运动，它是一个很好的例子，表明我们的背景是如何的。如果
           <code>
            firstFrame
           </code>
           没有初始化，我们会把它保存然后继续处理视频的下一帧。（
           <strong>
            20-22行
           </strong>
           ）
          </p>
          <p>
           这里有一个关于示例视频第一帧的例子：
          </p>
          <p>
           上面这一帧满足我们的假设，视频的第一帧仅仅是一个静止的背景——没有运动。
          </p>
          <p>
           有了这个静止的背景图片，我们已经准备好实时运动检测和追踪了：
          </p>
         </div>
        </div>
        <blockquote>
         <div class="line number1 index0 alt2">
          <code class="python comments">
           # 计算当前帧和第一帧的不同
          </code>
         </div>
         <div class="line number2 index1 alt1">
          <code class="python spaces">
          </code>
          <code class="python plain">
           frameDelta
          </code>
          <code class="python keyword">
           =
          </code>
          <code class="python plain">
           cv2.absdiff(firstFrame, gray)
          </code>
         </div>
         <div class="line number3 index2 alt2">
          <code class="python spaces">
          </code>
          <code class="python plain">
           thresh
          </code>
          <code class="python keyword">
           =
          </code>
          <code class="python plain">
           cv2.threshold(frameDelta,
          </code>
          <code class="python value">
           25
          </code>
          <code class="python plain">
           ,
          </code>
          <code class="python value">
           255
          </code>
          <code class="python plain">
           , cv2.THRESH_BINARY)[
          </code>
          <code class="python value">
           1
          </code>
          <code class="python plain">
           ]
          </code>
         </div>
         <div class="line number5 index4 alt2">
          <code class="python spaces">
          </code>
          <code class="python comments">
           # 扩展阀值图像填充孔洞，然后找到阀值图像上的轮廓
          </code>
         </div>
         <div class="line number6 index5 alt1">
          <code class="python spaces">
          </code>
          <code class="python plain">
           thresh
          </code>
          <code class="python keyword">
           =
          </code>
          <code class="python plain">
           cv2.dilate(thresh,
          </code>
          <code class="python color1">
           None
          </code>
          <code class="python plain">
           , iterations
          </code>
          <code class="python keyword">
           =
          </code>
          <code class="python value">
           2
          </code>
          <code class="python plain">
           )
          </code>
         </div>
         <div class="line number7 index6 alt2">
          <code class="python spaces">
          </code>
          <code class="python plain">
           (cnts, _)
          </code>
          <code class="python keyword">
           =
          </code>
          <code class="python plain">
           cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
          </code>
         </div>
         <div class="line number8 index7 alt1">
          <code class="python spaces">
          </code>
          <code class="python plain">
           cv2.CHAIN_APPROX_SIMPLE)
          </code>
         </div>
         <div class="line number10 index9 alt1">
          <code class="python spaces">
          </code>
          <code class="python comments">
           # 遍历轮廓
          </code>
         </div>
         <div class="line number11 index10 alt2">
          <code class="python spaces">
          </code>
          <code class="python keyword">
           for
          </code>
          <code class="python plain">
           c
          </code>
          <code class="python keyword">
           in
          </code>
          <code class="python plain">
           cnts:
          </code>
         </div>
         <div class="line number12 index11 alt1">
          <code class="python spaces">
          </code>
          <code class="python comments">
           # if the contour is too small, ignore it
          </code>
         </div>
         <div class="line number13 index12 alt2">
          <code class="python spaces">
          </code>
          <code class="python keyword">
           if
          </code>
          <code class="python plain">
           cv2.contourArea(c) &lt; args[
          </code>
          <code class="python string">
           "min_area"
          </code>
          <code class="python plain">
           ]:
          </code>
         </div>
         <div class="line number14 index13 alt1">
          <code class="python spaces">
          </code>
          <code class="python keyword">
           continue
          </code>
         </div>
         <div class="line number16 index15 alt1">
          <code class="python spaces">
          </code>
          <code class="python comments">
           # compute the bounding box for the contour, draw it on the frame,
          </code>
         </div>
         <div class="line number17 index16 alt2">
          <code class="python spaces">
          </code>
          <code class="python comments">
           # and update the text
          </code>
         </div>
         <div class="line number18 index17 alt1">
          <code class="python spaces">
          </code>
          <code class="python comments">
           # 计算轮廓的边界框，在当前帧中画出该框
          </code>
         </div>
         <div class="line number19 index18 alt2">
          <code class="python spaces">
          </code>
          <code class="python plain">
           (x, y, w, h)
          </code>
          <code class="python keyword">
           =
          </code>
          <code class="python plain">
           cv2.boundingRect(c)
          </code>
         </div>
         <div class="line number20 index19 alt1">
          <code class="python spaces">
          </code>
          <code class="python plain">
           cv2.rectangle(frame, (x, y), (x
          </code>
          <code class="python keyword">
           +
          </code>
          <code class="python plain">
           w, y
          </code>
          <code class="python keyword">
           +
          </code>
          <code class="python plain">
           h), (
          </code>
          <code class="python value">
           0
          </code>
          <code class="python plain">
           ,
          </code>
          <code class="python value">
           255
          </code>
          <code class="python plain">
           ,
          </code>
          <code class="python value">
           0
          </code>
          <code class="python plain">
           ),
          </code>
          <code class="python value">
           2
          </code>
          <code class="python plain">
           )
          </code>
         </div>
         <div class="line number21 index20 alt2">
          <code class="python spaces">
          </code>
          <code class="python plain">
           text
          </code>
          <code class="python keyword">
           =
          </code>
          <code class="python string">
           "Occupied"
          </code>
         </div>
        </blockquote>
        <div class="post-81593 post type-post status-publish format-standard hentry category-python tag-opencv tag-python odd" id="post-81593">
         <div class="entry">
          <p>
           现在我们已经从
           <code>
            firstFrame
           </code>
           变量对背景进行了建模，我们可以利用它来计算起始帧和视频流数据中后续新帧之间的不同。
          </p>
          <p>
           计算两帧的不同是一个简单的减法，我们使用两方相应的像素强度差的绝对值。（
           <strong>
            第二行
           </strong>
           ）
          </p>
          <p>
           delta = |background_model – current_frame|
          </p>
          <p>
           两帧差值图例如下：
          </p>
          <p>
           <img src="http://dataunion.org/wp-content/uploads/2015/06/6941baebgw1et0jkjei9oj20rs0a874z.jpg"/>
          </p>
          <p>
           注意到图片的背景是如何变为黑色的。然而，包含运动的区域（比如包含我自己走过房间动作的区域）会更亮一些。这以为这两帧差值大的地方是图片中发生移动的区域。
          </p>
          <p>
           我们随后在
           <strong>
            第3行
           </strong>
           对
           <code>
            frameDelta
           </code>
           进行阀值化来显示图片中像素强度值有显著变化的区域。如果差值小于25，我丢弃该像素将其设置为黑色（例如，背景）。如果差值大于25，我们将其设定为白色（例如，前景）。阀值化的差值图片如下：
          </p>
          <p>
           <img src="http://dataunion.org/wp-content/uploads/2015/06/6941baebgw1et0jkisiisj20rs09vt8v.jpg"/>
          </p>
          <p>
           再一次，注意到图片的背景是黑色的，而前景（运动发生的位置）是白色的。 有了这个阀值化的图片，只要简单的进行实施轮廓检测来找到白色区域的外轮廓线（
           <strong>
            第7行
           </strong>
           ）
          </p>
          <p>
           我们在第14行开始对轮廓线进行遍历，在15行滤掉小的，不相关的轮廓。 如果轮廓面积比我们提供的
           <code>
            --min-area
           </code>
           值大，我们会在前景和移动区域画边框线。（
           <strong>
            23-25行
           </strong>
           ）。我们同样会更新
           <code>
            text
           </code>
           状态字符串来表示这个房间”被占领“（Occupied）了
          </p>
          <div class="line number1 index0 alt2">
           <code class="python comments">
            # draw the text and timestamp on the frame
           </code>
          </div>
          <div class="line number2 index1 alt1">
           <code class="python spaces">
           </code>
           <code class="python comments">
            # 在当前帧上写文字以及时间戳
           </code>
          </div>
          <div class="line number3 index2 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            cv2.putText(frame,
           </code>
           <code class="python string">
            "Room Status: {}"
           </code>
           <code class="python plain">
            .
           </code>
           <code class="python functions">
            format
           </code>
           <code class="python plain">
            (text), (
           </code>
           <code class="python value">
            10
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python value">
            20
           </code>
           <code class="python plain">
            ),
           </code>
          </div>
          <div class="line number4 index3 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            cv2.FONT_HERSHEY_SIMPLEX,
           </code>
           <code class="python value">
            0.5
           </code>
           <code class="python plain">
            , (
           </code>
           <code class="python value">
            0
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python value">
            0
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python value">
            255
           </code>
           <code class="python plain">
            ),
           </code>
           <code class="python value">
            2
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number5 index4 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            cv2.putText(frame, datetime.datetime.now().strftime(
           </code>
           <code class="python string">
            "%A %d %B %Y %I:%M:%S%p"
           </code>
           <code class="python plain">
            ),
           </code>
          </div>
          <div class="line number6 index5 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            (
           </code>
           <code class="python value">
            10
           </code>
           <code class="python plain">
            , frame.shape[
           </code>
           <code class="python value">
            0
           </code>
           <code class="python plain">
            ]
           </code>
           <code class="python keyword">
            -
           </code>
           <code class="python value">
            10
           </code>
           <code class="python plain">
            ), cv2.FONT_HERSHEY_SIMPLEX,
           </code>
           <code class="python value">
            0.35
           </code>
           <code class="python plain">
            , (
           </code>
           <code class="python value">
            0
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python value">
            0
           </code>
           <code class="python plain">
            ,
           </code>
           <code class="python value">
            255
           </code>
           <code class="python plain">
            ),
           </code>
           <code class="python value">
            1
           </code>
           <code class="python plain">
            )
           </code>
          </div>
          <div class="line number8 index7 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            显示当前帧并记录用户是否按下按键
           </code>
          </div>
          <div class="line number9 index8 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            cv2.imshow(
           </code>
           <code class="python string">
            "Security Feed"
           </code>
           <code class="python plain">
            , frame)
           </code>
          </div>
          <div class="line number10 index9 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            cv2.imshow(
           </code>
           <code class="python string">
            "Thresh"
           </code>
           <code class="python plain">
            , thresh)
           </code>
          </div>
          <div class="line number11 index10 alt2">
           <code class="python spaces">
           </code>
           <code class="python plain">
            cv2.imshow(
           </code>
           <code class="python string">
            "Frame Delta"
           </code>
           <code class="python plain">
            , frameDelta)
           </code>
          </div>
          <div class="line number12 index11 alt1">
           <code class="python spaces">
           </code>
           <code class="python plain">
            key
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python plain">
            cv2.waitKey(
           </code>
           <code class="python value">
            1
           </code>
           <code class="python plain">
            ) &amp;amp;
           </code>
           <code class="python value">
            0xFF
           </code>
          </div>
          <div class="line number14 index13 alt1">
           <code class="python spaces">
           </code>
           <code class="python comments">
            # 如果q键被按下，跳出循环
           </code>
          </div>
          <div class="line number15 index14 alt2">
           <code class="python spaces">
           </code>
           <code class="python keyword">
            if
           </code>
           <code class="python plain">
            key
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python keyword">
            =
           </code>
           <code class="python functions">
            ord
           </code>
           <code class="python plain">
            (
           </code>
           <code class="python string">
            "q"
           </code>
           <code class="python plain">
            ):
           </code>
          </div>
          <div class="line number16 index15 alt1">
           <code class="python spaces">
           </code>
           <code class="python keyword">
            break
           </code>
          </div>
          <div class="line number18 index17 alt1">
           <code class="python comments">
            # 清理摄像机资源并关闭打开的窗口
           </code>
          </div>
          <div class="line number19 index18 alt2">
           <code class="python plain">
            camera.release()
           </code>
          </div>
          <div class="line number20 index19 alt1">
           <code class="python plain">
            cv2.destroyAllWindows()
           </code>
          </div>
          <div>
          </div>
          <p>
           <strong>
            11-13行
           </strong>
           显示了我的工作成果，运行我们可以在视频中看到是否检测到了运动，使用帧差值和阀值图像我们可以调试我们的脚本。
          </p>
          <p>
           <strong>
            注意：
           </strong>
           如果你下载了本文的源代码并打算应用到你自己的视频文件上，你可能需要改变
           <code>
            cv2.threshold
           </code>
           的值和
           <code>
            --min-area
           </code>
           参数来获得你所在光照环境下的最佳效果。
          </p>
          <p>
           最后，
           <strong>
            22行和23行
           </strong>
           清理并释放了视频流的指针。
          </p>
          <h2>
           结果
          </h2>
          <p>
           显然，我要确定我们的运动监测系统可以在James那个偷酒贼再次造访的之前能够正常工作——我们将在本系列第二篇文章中谈到他。为了测试我们使用Python和OpenCV搭建的运动监测系统，我录制了两个视频文件。
          </p>
          <p>
           第一个文件是
           <code>
            example_01.mp4
           </code>
           ，监视了我公寓的正门，当门被打开时完成检测。第二个文件是
           <code>
            example_02.mp4
           </code>
           使用安装在橱柜上的树莓派录制的。它监控厨房和客厅，当有人在其中走动的时候完成检测。
          </p>
          <p>
           让我们给我们简单的探测器一次尝试的机会，打开终端并执行下面指令：
          </p>
          <p>
           <code class="python plain">
            $ python motion_detector.py
           </code>
           <code class="python keyword">
            -
           </code>
           <code class="python keyword">
            -
           </code>
           <code class="python plain">
            video videos
           </code>
           <code class="python keyword">
            /
           </code>
           <code class="python plain">
            example_01.mp4
           </code>
          </p>
          <p>
           下图是一个 gif 图，显示来自探测器的一些静止帧数据。
          </p>
          <p>
           注意到在门被打开前没有进行运动检测——然后我们可以检测到我自己从门中走过。你可以在这里看到全部视频：
          </p>
          <p>
           <a href="http://www.youtube.com/embed/fi4LORwk8Fc?feature=oembed" target="_blank">
            http://www.youtube.com/embed/fi4LORwk8Fc?feature=oembed
           </a>
          </p>
          <p>
           现在，我安装在用于监视厨房和客厅的摄像机表现如何呢？然我们一探究竟。输入下面命令：
          </p>
          <p>
           <code class="python plain">
            $ python motion_detector.py
           </code>
           <code class="python keyword">
            -
           </code>
           <code class="python keyword">
            -
           </code>
           <code class="python plain">
            video videos
           </code>
           <code class="python keyword">
            /
           </code>
           <code class="python plain">
            example_02.mp4
           </code>
          </p>
          <p>
           来自第二个视频文件的结果样本如下：
          </p>
          <p>
           <img src="http://dataunion.org/wp-content/uploads/2015/06/6941baebgw1et0jkh8pnog20h20cg1kx.gif"/>
          </p>
          <p>
           同样，这里是我们运动检测结果的完整视频：
          </p>
          <p>
           <a href="http://www.youtube.com/embed/36j238XtcIE?feature=oembed" target="_blank">
            http://www.youtube.com/embed/36j238XtcIE?feature=oembed
           </a>
          </p>
          <p>
           正如你看到的，我们的运动检测系统尽管非常简单，但表现还不错！我们可以正常检测到我进入客厅和离开房间。
          </p>
          <p>
           然而，现实来讲，结果还远远谈不上完美。尽管只有一个人在屋内走动，我们却得到了多个外框——这和理想状态相差甚远。而且我可以看到，微小的光线变化，比如阴影和墙面反射，都触发了假阳性的运动检测结果。
          </p>
          <p>
           为了解决这些问题，我们依靠OpenCV中更加强大的背景移除方法，这些方法对阴影和少量的反射进行了处理。（我将在未来的文章中谈到这些更为先进的背景移除/前景检测方法）
          </p>
          <p>
           <strong>
            但是于此同时，请考虑一下我们的最终目标
           </strong>
          </p>
          <p>
           这个系统，尽管是在我们的笔记本/台式机系统上开发的，却是为了要部署在树莓派上，树莓派的计算资源非常有限。因此，我们需要让我们的运动检测方法保持简单和快速。我们的运动检测系统并不完美，很不幸这是一个不利的方面，但是对于我们特定的项目，它仍然能够很好的完成工作。
          </p>
          <p>
           最后，如果你想要利用你的摄像头的原始视频流来进行运动检测，空着
           <code>
            --video
           </code>
           选项即可。
          </p>
          <blockquote>
           <p>
            $ python motion_detector.py
           </p>
          </blockquote>
          <h2>
           小结
          </h2>
          <p>
           通过本文，我们已经认识到我的朋友James是一个偷酒贼。真是个混蛋啊！
          </p>
          <p>
           为了能抓他个人赃并获，我们决定使用Python和OpenCV建立一个运动检测和追踪系统。这个系统可以获取视频流并分析它们获取运动。考虑到我们所使用的方法，能够得到可以接受的监测结果。
          </p>
          <p>
           最终目标是要把本系统部署在树莓派上，因此我们没有依赖OpenCV中一些比较先进的背景移除方法。相反，我们依赖一个简单，但合理高效的假设——视频的第一帧仅仅包含我们想要建模的背景，而不包括其他任何东西。
          </p>
          <p>
           在这个假设下，我们可以实施背景移除，检测图片中的运动，在检测到运动的区域画出轮廓框。
          </p>
          <p>
           在这个关于运动检测系列文章的
           <strong>
            第二部分
           </strong>
           ，我们会
           <strong>
            更新代码使其在树莓派上运行
           </strong>
           。
          </p>
          <p>
           我们同样会
           <strong>
            集成Dropbox API
           </strong>
           ，允许我们监控家用监控系统并且当我们的系统检测到运动时，获取实时更新数据。
          </p>
          <p>
           敬请期待！
          </p>
         </div>
        </div>
       </div>
       <p>
        <a href="http://www.jobbole.com/members/hanxiaomax">
         艾凌风
        </a>
        翻译  英文出处：
        <a href="http://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/" target="_blank">
         www.pyimagesearch.com
        </a>
       </p>
      </div>
      <div>
       <strong>
        注：转载文章均来自于公开网络，仅供学习使用，不会用于任何商业用途，如果侵犯到原作者的权益，请您与我们联系删除或者授权事宜，联系邮箱：contact@dataunion.org。转载数盟网站文章请注明原文章作者，否则产生的任何版权纠纷与数盟无关。
       </strong>
      </div>
      <!--content_text-->
      <div class="fenxian">
       <!-- JiaThis Button BEGIN -->
       <div class="jiathis_style_32x32">
        <p class="jiathis_button_weixin">
        </p>
        <p class="jiathis_button_tsina">
        </p>
        <p class="jiathis_button_qzone">
        </p>
        <p class="jiathis_button_cqq">
        </p>
        <p class="jiathis_button_tumblr">
        </p>
        <a class="jiathis jiathis_txt jtico jtico_jiathis" href="http://www.jiathis.com/share" target="_blank">
        </a>
        <p class="jiathis_counter_style">
        </p>
       </div>
       <!-- JiaThis Button END -->
      </div>
     </article>
     <!--content-->
     <!--相关文章-->
     <div class="xianguan">
      <div class="xianguantitle">
       相关文章！
      </div>
      <ul class="pic">
       <li>
        <a href="http://dataunion.org/20824.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/09/t018630756a7e263b33-300x165.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/20824.html" rel="bookmark" title="如何判断一笔交易是否属于欺诈？你只是需要一点数据挖掘">
         如何判断一笔交易是否属于欺诈？你只是需要一点数据挖掘
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/20820.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/09/1-300x200.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/20820.html" rel="bookmark" title="人们对Python在企业级开发中的10大误解">
         人们对Python在企业级开发中的10大误解
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/20811.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/09/t0133fcacae8523307b_副本-300x200.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/20811.html" rel="bookmark" title="大神亲传：26条深度学习的金科玉律！">
         大神亲传：26条深度学习的金科玉律！
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/20808.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/09/640.webp-11-300x137.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/20808.html" rel="bookmark" title="我们是如何在一张地图上表现86万个数据的">
         我们是如何在一张地图上表现86万个数据的
        </a>
       </li>
      </ul>
     </div>
     <!--相关文章-->
     <div class="comment" id="comments">
      <!-- You can start editing here. -->
      <!-- If comments are open, but there are no comments. -->
      <div class="title">
       期待你一针见血的评论，Come on！
      </div>
      <div id="respond">
       <p>
        不用想啦，马上
        <a href="http://dataunion.org/wp-login.php?redirect_to=http%3A%2F%2Fdataunion.org%2F19514.html">
         "登录"
        </a>
        发表自已的想法.
       </p>
      </div>
     </div>
     <!-- .nav-single -->
    </div>
    <!--Container End-->
    <aside id="sitebar">
     <div class="sitebar_list2">
      <div class="wptag">
       <span class="tagtitle">
        热门标签+
       </span>
       <div class="tagg">
        <ul class="menu" id="menu-%e5%8f%8b%e6%83%85%e9%93%be%e6%8e%a5">
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1605" id="menu-item-1605">
          <a href="http://taidizh.com/">
           泰迪智慧
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-20884" id="menu-item-20884">
          <a href="http://www.transwarp.cn/">
           星环科技
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-3538" id="menu-item-3538">
          <a href="http://datall.org/">
           珈和遥感
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-20888" id="menu-item-20888">
          <a href="http://www.chinahadoop.cn/">
           小象学院
          </a>
         </li>
        </ul>
       </div>
      </div>
     </div>
     <div class="sitebar_list">
      <div class="textwidget">
       <div align="center">
        <a href="http://study.163.com/course/courseMain.htm?courseId=991022" target="_blank">
         <img src="http://dataunion.org/wp-content/uploads/2016/03/dv.jpg"/>
        </a>
       </div>
      </div>
     </div>
     <div class="sitebar_list">
      <h4 class="sitebar_title">
       文章分类
      </h4>
      <div class="tagcloud">
       <a class="tag-link-44" href="http://dataunion.org/category/industry/demo" style="font-size: 10.204724409449pt;" title="4个话题">
        Demo展示
       </a>
       <a class="tag-link-31" href="http://dataunion.org/category/experts" style="font-size: 15.826771653543pt;" title="52个话题">
        专家团队
       </a>
       <a class="tag-link-870" href="http://dataunion.org/category/tech/ai" style="font-size: 19.795275590551pt;" title="273个话题">
        人工智能
       </a>
       <a class="tag-link-488" href="http://dataunion.org/category/%e5%8a%a0%e5%85%a5%e6%95%b0%e7%9b%9f" style="font-size: 8pt;" title="1个话题">
        加入数盟
       </a>
       <a class="tag-link-869" href="http://dataunion.org/category/tech/viz" style="font-size: 17.204724409449pt;" title="93个话题">
        可视化
       </a>
       <a class="tag-link-30" href="http://dataunion.org/category/partners" style="font-size: 10.645669291339pt;" title="5个话题">
        合作伙伴
       </a>
       <a class="tag-link-889" href="http://dataunion.org/category/parterc" style="font-size: 11.582677165354pt;" title="8个话题">
        合作会议
       </a>
       <a class="tag-link-104" href="http://dataunion.org/category/books" style="font-size: 12.96062992126pt;" title="15个话题">
        图书
       </a>
       <a class="tag-link-220" href="http://dataunion.org/category/tech/base" style="font-size: 19.850393700787pt;" title="281个话题">
        基础架构
       </a>
       <a class="tag-link-219" href="http://dataunion.org/category/tech/analysis" style="font-size: 19.409448818898pt;" title="232个话题">
        数据分析
       </a>
       <a class="tag-link-887" href="http://dataunion.org/category/tech/dm" style="font-size: 13.291338582677pt;" title="17个话题">
        数据挖掘
       </a>
       <a class="tag-link-34" href="http://dataunion.org/category/tech" style="font-size: 20.732283464567pt;" title="404个话题">
        文章
       </a>
       <a class="tag-link-1" href="http://dataunion.org/category/uncategorized" style="font-size: 22pt;" title="693个话题">
        未分类
       </a>
       <a class="tag-link-4" href="http://dataunion.org/category/events" style="font-size: 14.503937007874pt;" title="29个话题">
        活动
       </a>
       <a class="tag-link-890" href="http://dataunion.org/category/tech/%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0" style="font-size: 10.204724409449pt;" title="4个话题">
        深度学习
       </a>
       <a class="tag-link-221" href="http://dataunion.org/category/tech/devl" style="font-size: 18.968503937008pt;" title="193个话题">
        编程语言
       </a>
       <a class="tag-link-888" href="http://dataunion.org/category/career" style="font-size: 15.661417322835pt;" title="48个话题">
        职业规划
       </a>
       <a class="tag-link-5" href="http://dataunion.org/category/jobs" style="font-size: 14.11811023622pt;" title="25个话题">
        职位
       </a>
       <a class="tag-link-871" href="http://dataunion.org/category/industry" style="font-size: 15.716535433071pt;" title="49个话题">
        行业
       </a>
       <a class="tag-link-613" href="http://dataunion.org/category/industry/case" style="font-size: 16.984251968504pt;" title="84个话题">
        行业应用
       </a>
       <a class="tag-link-885" href="http://dataunion.org/category/industry/news" style="font-size: 17.425196850394pt;" title="102个话题">
        行业资讯
       </a>
       <a class="tag-link-10" href="http://dataunion.org/category/training" style="font-size: 14.228346456693pt;" title="26个话题">
        课程
       </a>
       <a class="tag-link-16" href="http://dataunion.org/category/sources" style="font-size: 15.661417322835pt;" title="48个话题">
        资源
       </a>
      </div>
     </div>
     <div class="sitebar_list">
      <h4 class="sitebar_title">
       功能
      </h4>
      <ul>
       <li>
        <a href="http://dataunion.org/wp-login.php?action=register">
         注册
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/wp-login.php">
         登录
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/feed">
         文章
         <abbr title="Really Simple Syndication">
          RSS
         </abbr>
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/comments/feed">
         评论
         <abbr title="Really Simple Syndication">
          RSS
         </abbr>
        </a>
       </li>
       <li>
        <a href="https://cn.wordpress.org/" title="基于WordPress，一个优美、先进的个人信息发布平台。">
         WordPress.org
        </a>
       </li>
      </ul>
     </div>
    </aside>
    <div class="clear">
    </div>
   </div>
   <!--main-->
   ﻿
   <footer id="dibu">
    <div class="about">
     <div class="right">
      <ul class="menu" id="menu-%e5%ba%95%e9%83%a8%e8%8f%9c%e5%8d%95">
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-18024" id="menu-item-18024">
        <a href="http://dataunion.org/category/partners">
         合作伙伴
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-20881" id="menu-item-20881">
        <a href="http://dataunion.org/contribute">
         文章投稿
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20872" id="menu-item-20872">
        <a href="http://dataunion.org/category/%e5%8a%a0%e5%85%a5%e6%95%b0%e7%9b%9f">
         加入数盟
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-22441" id="menu-item-22441">
        <a href="http://dataunion.org/f-links">
         友情链接
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-20874" id="menu-item-20874">
        <a href="http://dataunion.org/aboutus">
         关于数盟
        </a>
       </li>
      </ul>
      <p class="banquan">
       数盟社区        ，
        做最棒的数据科学社区
      </p>
     </div>
     <div class="left">
      <ul class="bottomlist">
       <li>
        <a href="http://weibo.com/DataScientistUnion  " target="_blank" 　title="">
         <img src="http://dataunion.org/wp-content/themes/yzipi/images/weibo.png"/>
        </a>
       </li>
       <li>
        <a class="cd-popup-trigger" href="http://dataunion.org/19514.html#0">
         <img src="http://dataunion.org/wp-content/themes/yzipi/images/weixin.png"/>
        </a>
       </li>
      </ul>
      <div class="cd-popup">
       <div class="cd-popup-container">
        <h1>
         扫描二维码,加微信公众号
        </h1>
        <img src="http://dataunion.org/wp-content/themes/yzipi/images/2014-12-06-1515289049.png"/>
        <a class="cd-popup-close" href="http://dataunion.org/19514.html">
        </a>
       </div>
       <!-- cd-popup-container -->
      </div>
      <!-- cd-popup -->
     </div>
    </div>
    <!--about-->
    <div class="bottom">
     <a href="http://dataunion.org/">
      数盟社区
     </a>
     <a href="http://www.miitbeian.gov.cn/" rel="external nofollow" target="_blank">
      京ICP备14026740号
     </a>
     联系我们：
     <a href="mailto:contact@dataunion.org" target="_blank">
      contact@dataunion.org
     </a>
     <div class="tongji">
     </div>
     <!--bottom-->
     <div class="scroll" id="scroll" style="display:none;">
      ︿
     </div>
    </div>
   </footer>
   <!--dibu-->
  </div>
 </body>
</html>